﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Easy.Common
{
    public class LogManager
    {
        public enum LogLevel
        {
            OFF = 0, FATAL = 1, ERROR = 2, WARN = 3, INFO = 4, DEBUG = 5, TRACE = 6
        }
        public delegate LogLevel GetLogLevel(LogLevel CurrentLogLevel, String ProjectName, String ModuleName);


        /// <summary>
        /// 设置LOG时是否自动刷新Log等级
        /// </summary>
        public static bool AutoRefreshLogLevel //使用委托自动刷新LogLevel 
        {
            get;
            set;
        }
        private static GetLogLevel LogLevelFunction;
        private static String LogPath = @"c:\TulingBuyLog\";

        /// <summary>
        /// 设置Log的当前等级
        /// </summary>
        public static LogLevel CurrentLogLevel
        {
            get;
            set;
        }//默认Log等级为关闭 请在使用前重新赋值
        

        /// <summary>
        /// 提交一个委托 用于动态刷新LOG等级
        /// </summary>
        /// <param name="GetLogLevelFunction">动态刷新LOG的委托</param>
        public static void BindLogLevelFunction(GetLogLevel GetLogLevelFunction)
        {
            LogLevelFunction = GetLogLevelFunction;
        }


        /// <summary>
        /// 解除委托
        /// </summary>
        public static void UnBindLogLevelFunction() //解除委托 终止动态刷新
        {
            LogLevelFunction = null;
        }

        private static void CreateLogFile(String ProjectName, String ModuleName)
        {
            try
            {
                if (!Directory.Exists(LogPath + ProjectName + "\\" + ModuleName))
                {
                    Directory.CreateDirectory(LogPath + ProjectName + "\\" + ModuleName);
                }
            }
            catch (Exception) { }
        }

        private static bool WriteLog(String ProjectName, String ModuleName, String msg, LogLevel WriteLogLevel)
        {
            try
            {
                FileStream FileWritter = new FileStream(LogPath + ProjectName + "\\" + ModuleName + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".log", FileMode.Append, FileAccess.Write, FileShare.ReadWrite,8,true);
                String str = WriteLogLevel.ToString() + " :  " + msg + "   -" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n";
                byte[] strbytes=System.Text.Encoding.Default.GetBytes(str);
                FileWritter.Write(strbytes, 0, strbytes.Length);
                FileWritter.Close();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public static void RefreshLogLevel(String ProjectName, String ModuleName) //使用委托立即刷新Log状态
        {
            try
            {
                CurrentLogLevel = LogLevelFunction.Invoke(CurrentLogLevel,ProjectName,ModuleName);
            }
            catch (Exception)
            {

            }
        }

        /// <summary>
        /// 自动刷新Log
        /// </summary>
        /// <param name="ProjectName"></param>
        /// <param name="ModuleName"></param>
        private static void AutoRefresh(String ProjectName, String ModuleName)
        {
            if (!AutoRefreshLogLevel) return;
            else RefreshLogLevel(ProjectName, ModuleName);
        }


        /// <summary>
        /// 当LOG等级如果为Trace或更高等级时向%LogPath%/{ProjectName}/{ModuleName}/{今天日期}.log文件追加一条跟踪级别的LOG
        /// </summary>
        /// <param name="ProjectName">Log所属的项目名</param>
        /// <param name="ModuleName">Log所属的模块名</param>
        /// <param name="msg">书写LOG的信息</param>
        /// <returns></returns>
        public static bool WriteTraceLog(String ProjectName, String ModuleName, String msg)
        {
            AutoRefresh(ProjectName, ModuleName);
            if (!((int)CurrentLogLevel >= 6)) return false;
            CreateLogFile(ProjectName, ModuleName);
            return WriteLog(ProjectName, ModuleName, msg, LogLevel.TRACE);
        }


        /// <summary>
        /// 当LOG等级如果为Debug或更高等级时向%LogPath%/{ProjectName}/{ModuleName}/{今天日期}.log文件追加一条调试级别的LOG
        /// </summary>
        /// <param name="ProjectName">Log所属的项目名</param>
        /// <param name="ModuleName">Log所属的模块名</param>
        /// <param name="msg">书写LOG的信息</param>
        /// <returns></returns>
        public static bool WriteDebugLog(String ProjectName, String ModuleName, String msg)
        {
            AutoRefresh(ProjectName, ModuleName);
            if (!((int)CurrentLogLevel >= 5)) return false;
            CreateLogFile(ProjectName, ModuleName);
            return WriteLog(ProjectName, ModuleName, msg, LogLevel.DEBUG);
        }


        /// <summary>
        /// 当LOG等级如果为Info或更高等级时向%LogPath%/{ProjectName}/{ModuleName}/{今天日期}.log文件追加一条信息级别的LOG
        /// </summary>
        /// <param name="ProjectName">Log所属的项目名</param>
        /// <param name="ModuleName">Log所属的模块名</param>
        /// <param name="msg">书写LOG的信息</param>
        /// <returns></returns>
        public static bool WriteInfoLog(String ProjectName, String ModuleName, String msg)
        {
            AutoRefresh(ProjectName, ModuleName);
            if (!((int)CurrentLogLevel >= 4)) return false;
            CreateLogFile(ProjectName, ModuleName);
            return WriteLog(ProjectName, ModuleName, msg, LogLevel.INFO);
        }


        /// <summary>
        /// 当LOG等级如果为Warn或更高等级时向%LogPath%/{ProjectName}/{ModuleName}/{今天日期}.log文件追加一条警告级别的LOG
        /// </summary>
        /// <param name="ProjectName">Log所属的项目名</param>
        /// <param name="ModuleName">Log所属的模块名</param>
        /// <param name="msg">书写LOG的信息</param>
        /// <returns></returns>
        public static bool WriteWarnLog(String ProjectName, String ModuleName, String msg)
        {
            AutoRefresh(ProjectName, ModuleName);
            if (!((int)CurrentLogLevel >= 3)) return false;
            CreateLogFile(ProjectName, ModuleName);
            return WriteLog(ProjectName, ModuleName, msg, LogLevel.WARN);
        }


        /// <summary>
        /// 当LOG等级如果为Error或更高等级时向%LogPath%/{ProjectName}/{ModuleName}/{今天日期}.log文件追加一条错误级别的LOG
        /// </summary>
        /// <param name="ProjectName">Log所属的项目名</param>
        /// <param name="ModuleName">Log所属的模块名</param>
        /// <param name="msg">书写LOG的信息</param>
        /// <returns></returns>
        public static bool WriteErrorLog(String ProjectName, String ModuleName, String msg)
        {
            AutoRefresh(ProjectName, ModuleName);
            if (!((int)CurrentLogLevel >= 2)) return false;
            CreateLogFile(ProjectName, ModuleName);
            return WriteLog(ProjectName, ModuleName, msg, LogLevel.ERROR);
        }
        
        /// <summary>
        /// 当LOG等级如果为Faital或更高等级时向%LogPath%/{ProjectName}/{ModuleName}/{今天日期}.log文件追加一条崩溃级别的LOG
        /// </summary>
        /// <param name="ProjectName">Log所属的项目名</param>
        /// <param name="ModuleName">Log所属的模块名</param>
        /// <param name="msg">书写LOG的信息</param>
        /// <returns></returns>
        public static bool WriteFaitalLog(String ProjectName, String ModuleName, String msg)
        {
            AutoRefresh(ProjectName, ModuleName);
            if (!((int)CurrentLogLevel >= 1)) return false;
            CreateLogFile(ProjectName, ModuleName);
            return WriteLog(ProjectName, ModuleName, msg, LogLevel.FATAL);
        }

    }
}
